package com.powernode.strategy.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.powernode.config.WxParamConfig;
import com.powernode.constant.AuthConstants;
import com.powernode.domain.LoginMember;
import com.powernode.mapper.LoginMemberMapper;
import com.powernode.model.SecurityUser;
import com.powernode.strategy.LoginStrategy;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/*
 * 商城购物系统登录具体实现的策略
 * @author RenBoQing
 * @date 2024/9/1 12:08
 * @param null
 * @return null
 */
@Service(AuthConstants.MEMBER_LOGIN)
public class MemberLoginStrategy implements LoginStrategy {
    @Autowired
    private WxParamConfig wxParamConfig;
    @Autowired
    private LoginMemberMapper loginMemberMapper;

    /**
     * 编写用户购物车系统会员的登录逻辑
     *
     * @param username 用户名
     * @return
     */
    @Override
    public UserDetails realLogin(String username) {
        // 调用微信接口服务中的 登录校验appid 和appsecrect code等
        //String url = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";
        // 获取对应的token数据
        String realUrl = String.format(wxParamConfig.getUrl(), wxParamConfig.getAppid(), wxParamConfig.getSecret(), username);
        String jsonStr = HttpUtil.get(realUrl);
        // 使用fastjson将 登录的校验的json字符串转化为 json对象
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        // 获取openid
        String openid = jsonObject.getString("openid");
        //判断是否有值
        if (!StringUtils.hasText(openid)) {
            throw new InternalAuthenticationServiceException("登录异常请重试");
        }
        // 根据会员的openid 查询会员对象
        LoginMember loginMember = loginMemberMapper.selectOne(new LambdaQueryWrapper<LoginMember>()
                .eq(LoginMember::getOpenId, openid)
        );
        // 判断会员是否存在
        if (ObjectUtil.isNotEmpty(loginMember)) {
            // 不存在 创建用户
            loginMember = registerMember(loginMember.getOpenId());
        }
        // 判断会员的状态
        if (!loginMember.getStatus().equals(1)) {
            throw new InternalAuthenticationServiceException("账号状态异常,请联系管理员");
        }
        // 会员存在而且 会员状态正常
        SecurityUser securityUser = new SecurityUser();
        securityUser.setUserId(Long.valueOf(loginMember.getId()));
        securityUser.setLoginType(AuthConstants.MEMBER_LOGIN);
        securityUser.setUsername(openid);
        securityUser.setStatus(loginMember.getStatus());
        securityUser.setPassword(wxParamConfig.getPwd());
        securityUser.setOpenid(loginMember.getOpenId());
        return securityUser;
    }

    /*
     * 创建会员用户
     * @author RenBoQing
     * @date 2024/9/1 22:09
     * @param openId
     * @return com.powernode.domain.LoginMember
     */
    private LoginMember registerMember(String openId) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String remoteAddr = request.getRemoteAddr();
        LoginMember loginMember = new LoginMember();
        loginMember.setOpenId(openId);
        loginMember.setStatus(1);
        loginMember.setCreateTime(new Date());
        loginMember.setUpdateTime(new Date());
        loginMember.setUserLasttime(new Date());
        loginMember.setUserLastip(remoteAddr);
        loginMember.setUserRegip(remoteAddr);
        // 业务积分
        loginMember.setScore(0);
        loginMemberMapper.insert(loginMember);
        return loginMember;
    }
}